package umich.max.geolocation.statistics;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import max.nlp.dal.blog.blogger.BlogAuthorProfile;
import max.nlp.dal.blog.blogger.BloggerDB;
import max.nlp.dal.blog.blogger.ParsedLocation;

import com.mongodb.DBCursor;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class ProfileStatistics {

	public static void printProfileStatistics() {
		BloggerDB db = BloggerDB.getInstance();

		int numProfiles = 0;
		int numProfilesWithLoc = 0;
		int numProfilesWithCity = 0;
		int numProfilesWithState = 0;
		int numProfilesWithCountry = 0;

		DBCursor itr = db.getProfileIterator();
		while (itr.hasNext()) {
			BlogAuthorProfile profile = new BlogAuthorProfile(itr.next());
			ParsedLocation pl = profile.getParsedLocation();
			numProfiles++;
			if (pl != null) {
				numProfilesWithLoc++;
				if (pl.getCity() != null)
					numProfilesWithCity++;
				if (pl.getState() != null)
					numProfilesWithState++;
				if (pl.getCountry() != null)
					numProfilesWithCountry++;
			}
		}
		System.out.println("Number of profiles: " + numProfiles);
		System.out.println("Number of profiles with location: "
				+ numProfilesWithLoc);
		System.out.println("Number of profiles with city: "
				+ numProfilesWithCity);
		System.out.println("Number of profiles with state: "
				+ numProfilesWithState);
		System.out.println("Number of profiles with country: "
				+ numProfilesWithCountry);

	}

	public static void printStateStatistics() {
		BloggerDB db = BloggerDB.getInstance();
		Map<String, Integer> counts = new HashMap<String, Integer>();
		DBCursor itr = db.getProfileIterator();
		while (itr.hasNext()) {
			BlogAuthorProfile profile = new BlogAuthorProfile(itr.next()
					.toMap());
			ParsedLocation pl = profile.getParsedLocation();
			if (pl != null) {
				String state = pl.getState();
				Integer count = counts.get(state);
				if (count == null) {
					counts.put(state, 1);
				} else
					counts.put(state, count + 1);
			}

		}

		List<Map.Entry<String, Integer>> entries = new ArrayList(
				counts.entrySet());
		Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {

			public int compare(Entry<String, Integer> o1,
					Entry<String, Integer> o2) {
				if (o1.getValue() == null && o2.getValue() == null)
					return 0;
				if (o1.getValue() == null)
					return -1; // Nulls last
				return -o1.getValue().compareTo(o2.getValue());
			}
		});
		int profilesWithStates = 0;

		for (Entry<String, Integer> e : entries) {
			System.out.println(e);
			profilesWithStates = profilesWithStates + e.getValue();
		}
	}

	public static Map<String, Integer> getStateStatistics() {
		BloggerDB db = BloggerDB.getInstance();
		Map<String, Integer> counts = new HashMap<String, Integer>();
		DBCursor itr = db.getProfileIterator();
		while (itr.hasNext()) {
			BlogAuthorProfile profile = new BlogAuthorProfile(itr.next()
					.toMap());
			ParsedLocation pl = profile.getParsedLocation();
			if (pl != null) {
				String state = pl.getState();
				Integer count = counts.get(state);
				if (count == null) {
					counts.put(state, 1);
				} else
					counts.put(state, count + 1);
			}
		}
		return counts;

	}

	public static Map<String, Integer> getCityStatistics() {
		BloggerDB db = BloggerDB.getInstance();
		Map<String, Integer> counts = new HashMap<String, Integer>();
		DBCursor itr = db.getProfileIterator();
		while (itr.hasNext()) {
			BlogAuthorProfile profile = new BlogAuthorProfile(itr.next()
					.toMap());
			ParsedLocation pl = profile.getParsedLocation();
			if (pl != null) {
				String city = pl.getCity();
				Integer count = counts.get(city);
				if (count == null) {
					counts.put(city, 1);
				} else
					counts.put(city, count + 1);
			}
		}
		return counts;

	}

	public static void printCityStatistics() {
		BloggerDB db = BloggerDB.getInstance();
		Map<String, Integer> counts = new HashMap<String, Integer>();
		DBCursor itr = db.getProfileIterator();
		while (itr.hasNext()) {
			BlogAuthorProfile profile = new BlogAuthorProfile(itr.next()
					.toMap());
			ParsedLocation pl = profile.getParsedLocation();
			if (pl != null) {
				String city = pl.getCity();
				Integer count = counts.get(city);
				if (count == null) {
					counts.put(city, 1);
				} else
					counts.put(city, count + 1);
			}

		}

		List<Map.Entry<String, Integer>> entries = new ArrayList(
				counts.entrySet());
		Collections.sort(entries, new Comparator<Map.Entry<String, Integer>>() {

			public int compare(Entry<String, Integer> o1,
					Entry<String, Integer> o2) {
				if (o1.getValue() == null && o2.getValue() == null)
					return 0;
				if (o1.getValue() == null)
					return -1; // Nulls last
				return -o1.getValue().compareTo(o2.getValue());
			}
		});
		int profilesWithCities = 0;
		for (Entry<String, Integer> e : entries) {
			System.out.println(e);
			profilesWithCities = profilesWithCities + e.getValue();
		}
		System.out.println(profilesWithCities);
	}

	public static void main(String[] args) {
		 printStateStatistics();
//		 printCityStatistics();
//		printProfileStatistics();

	}

}
